package com.hxzy.config.security.filter;

import com.hxzy.token.TokenService;
import com.hxzy.vo.AdminLoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 管理员令牌令牌拦截器 public class AdminTokenInterceptor implements HandlerInterceptor  自定义拦截器
 * spring security框架基于 Filter的，FIlter执行优化级大于 HandlerInterceptor的
 */
@Component
public class AdminTokenFilter extends OncePerRequestFilter {

    @Autowired
    private TokenService tokenService;

//    @Override
//    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//       //根据请求header得到令牌，来获取当前用户是谁
//        AdminLoginVO adminLoginVO= this.tokenService.getAdminLoginUser(request,response);
//        //写入到本地线程池中
//        if(adminLoginVO!=null){
//            NewBeeThreadLocal.adminLoginVOThreadLocal.set(adminLoginVO);
//            return true;
//        }
//        return false;
//    }

//    @Override
//    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        //移出当前线程的数据
//        NewBeeThreadLocal.adminLoginVOThreadLocal.remove();
//    }

    /**
     * 基于spring security的拦截器
     * @param request
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //根据请求header得到令牌，来获取当前用户是谁
        AdminLoginVO adminLoginVO= this.tokenService.getAdminLoginUser(request,response);
        //判断当前AdminLogVO 实现了UserDetails接口的 是否为null,   放到SpringSecurity SecurityContextHolder里面
        // 模拟一个 UsernamePasswordAuthenticationToke（当前登录用户，BCrypt加密的密码， 权限Collection<? extends GrantedAuthority> authorities）

        //SecurityContextHolder.getContext().getAuthentication().getPrincipal() 类 当做为 NewBeeThreadLocal.adminLoginVOThreadLocal. 本地线程池
        if(adminLoginVO!=null ){
            // 当前adminLoginVO 放到本地线程池中，后面的请求才能用到
            UsernamePasswordAuthenticationToken  authenticationToken=new UsernamePasswordAuthenticationToken(adminLoginVO,adminLoginVO.getPassword(),adminLoginVO.getAuthorities());

            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            // 放到本地线程池里面
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }

        //放行
        filterChain.doFilter(request,response);
    }
}
